package com.mt.repair.service.repairManagement.impl;

import com.mt.common.core.security.RedisUtil;
import com.mt.common.core.web.JsonResult;
import com.mt.repair.dao.repairManagement.MessageDao;

import com.mt.common.core.exception.BusinessException;
import com.mt.common.core.web.base.PageDTO;
import com.mt.common.core.web.base.PageResultDTO;
import com.mt.common.core.web.base.BaseEntity;
import com.mt.common.core.web.BaseService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.mt.repair.entity.repairManagement.Message;
import com.mt.repair.service.repairManagement.MessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
@Transactional
public class MessageServiceBean extends BaseService implements MessageService {

    private static Logger logger = LogManager.getLogger();

	@Autowired
	private MessageDao messageDao;

	@Resource
	private RedisTemplate<String, List<Message>> redisTemplate;

	@Autowired
	StringRedisTemplate stringRedisTemplate;

	@Autowired
	private RedisUtil redisUtil;


	/**
	 * 根据分页参数查询消息中心集合
	 *
	 * @param pageDTO 分页条件
	 */
	@Override
	public PageResultDTO findMessages(PageDTO pageDTO){
        pageDTO.setStartIndex((pageDTO.getCurrentPage()-1)*pageDTO.getPageSize());
		//TODO:请在此校验参数的合法性
		this.validateFindMessages(pageDTO);
		List<Message> messageDTOS = this.messageDao.findMessages(pageDTO);
		Long totalCount = this.messageDao.findMessageTotalCount(pageDTO);

		PageResultDTO pageResultDTO = new PageResultDTO();
		pageResultDTO.setTotalCount(totalCount);
		pageResultDTO.setDatas(messageDTOS);

		return pageResultDTO;
	}

	/**
	 * 查询全部消息中心集合
	 *
	 */
	@Override
	public List<Message> findAllMessages(){
		return this.messageDao.findAllMessages();
	}

	/**
	 * 查询所有消息中心集合(只提取ID 和 Name)
	 *
	 */
	@Override
	public List<Message> findAllMessagesWithIdName(){
		//TODO:请在此校验参数的合法性
		this.validateFindAllMessagesWithIdName();
		return this.messageDao.findAllMessagesWithIdName();
	}

	/**
	 * 根据名称查询消息中心集合(只提取ID 和 Name)
	 *
	 * @param messageName 名称
	 */
	@Override
	public List<Message> findMessagesWithIdNameByName(String messageName){
		//TODO:请在此校验参数的合法性
		this.validateFindMessagesWithIdNameByName(messageName);
		//TODO:缓存取对应参数
		Set<String> keys = stringRedisTemplate.keys("searchData:Message_where_messageName_" + messageName);
		List<Message> messages = new ArrayList<>();
		if (keys.isEmpty()) {
		messages = this.messageDao.findMessagesWithIdNameByName(messageName);
		redisTemplate.opsForValue().set("searchData:Message_where_messageName_" + messageName, messages, 30, TimeUnit.DAYS);
		} else {
		messages = redisTemplate.opsForValue().get("searchData:Message_where_messageName_" + messageName);
		}
		return messages;
	}

	/**
	 * 根据ID查询指定的消息中心(只提取ID 和 Name)
	 *
	 * @param messageId Id
	 */
	@Override
	public Message findMessagesWithIdNameById(Long messageId){
		//TODO:请在此校验参数的合法性
		this.validateFindMessagesWithIdNameById(messageId);
		return this.messageDao.findMessagesWithIdNameById(messageId);
	}

	/**
	 * 根据ID查询指定的消息中心
	 *
	 * @param messageId Id
	 */
	@Override
	public Message findMessage(Long messageId){
		//TODO:请在此校验参数的合法性
		this.validateFindMessage(messageId);
		return this.messageDao.findMessage(messageId);
	}

	/**
	 * 根据ID查询指定的消息中心(包含外键)
	 *
	 * @param messageId Id
	 */
	@Override
	public Message findMessageWithForeignName(Long messageId){
		//TODO:请在此校验参数的合法性
		this.validateFindMessageWithForeignName(messageId);
		return this.messageDao.findMessageWithForeignName(messageId);
	}

	/**
	 * 新增消息中心
	 *
	 * @param message 实体对象
	 */
	@Override
	public Message saveMessage(Message message){
		//TODO:请在此校验参数的合法性
		this.validateSaveMessage(message);
		//TODO:填充公共参数
		this.setSavePulicColumns(message);
		/*
		生成最新的chatList
		1、判断当前用户是否存在相应的chatList
		2、不存在，则
		 */
		//boolean b = redisUtil.hasKey("chatList-" + message.getFromUserId() + "-" + message.getToUserId());
		//if(!b){
		//	Long count=chatListService.findHasChatList(message.getFromUserId(), message.getToUserId());
		//	if(count<=0){
		//		ChatList chatList = new ChatList();
		//		chatList.setCreateDatetime(new Date());
		//		chatList.setUserId(message.getFromUserId());
		//		chatList.setToUserId(message.getToUserId());
		//		this.chatListService.saveChatList(chatList);
		//		redisUtil.set("chatList-" + message.getFromUserId() + "-" + message.getToUserId(),"true");
		//	}else{
		//
		//	}
		//}
		Long rows = this.messageDao.saveMessage(message);
		if(rows != 1)
		{
			String error = "新增保存消息中心出错，数据库应该返回1,但返回了 "+rows;
			throw new BusinessException(error);
		}
		return message;
	}

	/**
	 * 更新消息中心
	 *
	 * @param message 实体对象
	 */
	@Override
	public Message updateMessage(Message message){
		//TODO:请在此校验参数的合法性
		this.validateUpdateMessage(message);
		Long rows = this.messageDao.updateMessage(message);
		if(rows != 1)
		{
			String error = "修改保存消息中心出错，数据库应该返回1,但返回了 "+rows+",数据可能被删除";
			throw new BusinessException(error);
		}
		return message;
	}

	/**
	 * 根据ID删除消息中心
	 *
	 * @param messageId ID
	 */
	@Override
	public void deleteMessage(Long messageId){
		//TODO:请在此校验参数的合法性
		this.validateDeleteMessage(messageId);

		Map<Class<? extends BaseEntity>,EntityUsage> entityUsageMap = this.checkForeignEntity(Message.class, messageId);
		if(entityUsageMap != null && entityUsageMap.size() >0){
			StringBuilder errors = new StringBuilder();
			errors.append("计划删除的数据正在被以下数引用\n");
			for(EntityUsage entityUsage : entityUsageMap.values()){
				errors.append("\t").append(entityUsage.getEntityLabel()).append("\n");
				for(Map.Entry<Long,String> entry : entityUsage.getUsageIdNames().entrySet() ){
					errors.append("\t\t").append(entry.getKey()).append("\t").append(entry.getValue()).append("\n");
				}
			}
			errors.append("，不能删除，请检查处理后再删除");
			throw  new BusinessException(errors.toString());
		}

		Long rows = this.messageDao.deleteMessage(messageId);
		if(rows != 1){
			String error = "删除消息中心出错，数据可能已经被删除";
			throw new BusinessException(error);
		}
	}

	@Override
	public Long countNotReadNum(Long toUserId) {
		return this.messageDao.countNotReadNum(toUserId);
	}

	@Override
	public JsonResult readMessage(Long messageId) {
		Long rows=this.messageDao.readMessage(messageId);
		return rows==1L?JsonResult.ok("已读成功"):JsonResult.error("已读失败，数据库修改数据条数为"+rows);
	}

	//TODO:---------------验证-------------------

	private void validateFindMessages(PageDTO pageDTO) {
	//TODO:请使用下面方法添加数据过滤条件
	//		pageDTO.addFilter("creatorId",this.getLoginUserId());
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateMessage()写法
	}

	private void validateFindMessagesWithIdNameByName(String messageName) {
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateMessage()写法
	}


	private void validateFindAllMessagesWithIdName() {
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateMessage()写法
	}

	private void validateFindMessagesWithIdNameById(Long messageId) {
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateMessage()写法
	}

	private void validateFindMessage(Long messageId) {
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateMessage()写法
	}

	private void validateFindMessageWithForeignName(Long messageId) {
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateMessage()写法
	}

	private void validateSaveMessage(Message message) {
	//不为空判断
	if (message.getEid() != null) {
	throw new BusinessException("非法请求");
	}
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateMessage()写法
	}

	private void validateUpdateMessage(Message message) {
	//不为空判断
	if (message.getEid() == null) {
	throw new BusinessException("唯一标识不能为空");
	}
	//是否存在判断
	if (this.messageDao.findMessageTotalCount(PageDTO.create(Message.FIELD_ID, message.getEid())) == 0) {
	throw new BusinessException("修改的消息中心 " + message.getName() + " 不存在，修改失败，请重试或联系管理员");
	}
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateMessage()写法
	}

	private void validateDeleteMessage(Long messageId) {
	//TODO:请完善数据校验规则和数据权限判断，如果有问题请抛出异常，参看下面validateUpdateMessage()写法
	}

	@Override
	public boolean canDownloadAttachment(String formName, Long id) {
	return true;
	}
}
